# -*- coding: utf-8 -*-
"""
提示词模板服务
负责将表单数据转换为结构化的AI提示词
"""

from typing import Dict, Optional
import logging

logger = logging.getLogger(__name__)


class PromptTemplateService:
    """
    提示词模板服务类
    提供表单数据到AI提示词的转换功能
    """
    
    # 字段映射配置
    FIELD_MAPPING = {
        'core_goal': '核心目标',
        'target_audience': '目标受众',
        'budget_per_person': '人均预算',
        'focus_area': '方案侧重点',
        'focus_point': '方案侧重点',  # 兼容性映射
        'gift_type_preference': '礼品类型偏好',
        'gift_preference': '礼品类型偏好',  # 兼容性映射
        'specific_product': '具体产品',
        'customer_preference': '客户偏好',
        'customer_pain_point': '客户痛点',
        'customer_pain_points': '客户痛点'  # 兼容性映射
    }
    
    # 处理指令模板
    PROCESSING_INSTRUCTIONS = """
你需要根据用户的需求，完善并输出以下内容：
a) 基于用户需求中的【{core_goal}】和【{target_audience}】，从策略库匹配最优核心策略
b) 基于a步骤推导出的核心策略和用户需求中的【{budget_per_person}】【{gift_preference}】，从礼品库推导具体推荐产品
c) 基于a和b两个步骤的结果再结合用户需求中的【{customer_pain_points}】和【{customer_preference}】，生成模块化方案，包含：
  · 需求解读与策略定位
  · 核心策略阐述（策略名称/主题）
  · 具体执行方案（礼品推荐+产品故事）
  · 精准的产品描述（用于AI生图提示词）
  · 后续营销路径（产品营销内容+营销动作）"""
    
    @classmethod
    def generate_prompt(
        cls,
        requirement_data: Dict
    ) -> Optional[str]:
        """
        生成结构化的AI提示词
        
        Args:
            requirement_data: 需求表单数据
            
        Returns:
            str: 生成的提示词，失败返回None
        """
        try:
            # 验证必要字段
            if not cls._validate_requirement_data(requirement_data):
                logger.error('需求数据验证失败')
                return None
            
            # 构建用户需求部分
            user_requirements = cls._build_user_requirements(requirement_data)
            
            # 构建处理指令部分
            processing_instructions = cls._build_processing_instructions(requirement_data)
            
            # 组装完整提示词
            prompt = f"""用户需求如下：
{user_requirements}

{processing_instructions}"""
            
            logger.info('提示词生成成功')
            return prompt
            
        except Exception as e:
            logger.error(f'生成提示词失败: {str(e)}')
            return None
    
    @classmethod
    def validate_requirements(cls, data: Dict) -> tuple:
        """
        公开的需求数据验证方法
        
        Args:
            data: 需求数据
            
        Returns:
            tuple: (是否有效, 缺失字段列表)
        """
        if not isinstance(data, dict):
            return False, ['数据格式错误']
        
        # 检查核心字段（必填字段）
        required_fields = [
            'core_goal', 'target_audience', 'budget_per_person',
            'focus_point', 'customer_preference', 'customer_pain_points'
        ]
        
        missing_fields = []
        for field in required_fields:
            # 检查多种可能的字段名（兼容性）
            field_variants = [field]
            if field == 'customer_pain_points':
                field_variants.append('customer_pain_point')
            elif field == 'focus_point':
                field_variants.append('focus_area')
            
            found = False
            for variant in field_variants:
                if data.get(variant) and str(data[variant]).strip():
                    found = True
                    break
            
            if not found:
                chinese_name = cls.FIELD_MAPPING.get(field, field)
                missing_fields.append(chinese_name)
        
        return len(missing_fields) == 0, missing_fields
    
    @classmethod
    def _validate_requirement_data(cls, data: Dict) -> bool:
        """
        验证需求数据的完整性
        
        Args:
            data: 需求数据
            
        Returns:
            bool: 验证结果
        """
        try:
            # 检查核心字段（支持字段兼容性）
            required_checks = [
                ('core_goal', ['core_goal']),
                ('target_audience', ['target_audience']),
                ('budget_per_person', ['budget_per_person']),
                ('focus_point', ['focus_point', 'focus_area']),
                ('customer_preference', ['customer_preference']),
                ('customer_pain_points', ['customer_pain_point', 'customer_pain_points'])
            ]
            
            for field_name, field_variants in required_checks:
                found = False
                for variant in field_variants:
                    if data.get(variant) and str(data[variant]).strip():
                        found = True
                        break
                
                if not found:
                    logger.warning(f'缺少必要字段: {field_name}')
                    return False
            
            return True
            
        except Exception as e:
            logger.error(f'数据验证异常: {str(e)}')
            return False
    
    @classmethod
    def _build_user_requirements(cls, data: Dict) -> str:
        """
        构建用户需求部分
        
        Args:
            data: 需求数据
            
        Returns:
            str: 格式化的用户需求文本
        """
        requirements_lines = []
        
        # 按照预定义顺序处理字段
        field_order = [
            'core_goal', 'target_audience', 'budget_per_person',
            'focus_area', 'focus_point', 'gift_type_preference', 'gift_preference', 'specific_product',
            'customer_preference', 'customer_pain_point', 'customer_pain_points'
        ]
        
        for field in field_order:
            value = data.get(field)
            if value and str(value).strip():
                field_name = cls.FIELD_MAPPING.get(field, field)
                requirements_lines.append(f'  * {field_name}：{str(value).strip()}')
        
        return '\n'.join(requirements_lines)
    
    @classmethod
    def _build_processing_instructions(cls, data: Dict) -> str:
        """
        构建处理指令部分
        
        Args:
            data: 需求数据
            
        Returns:
            str: 格式化的处理指令文本
        """
        try:
            # 提取关键值用于指令模板
            core_goal = data.get('core_goal', '').strip()
            target_audience = data.get('target_audience', '').strip()
            budget_per_person = data.get('budget_per_person', '').strip()
            
            # 兼容多种字段名
            gift_preference = (data.get('gift_type_preference') or data.get('gift_preference', '')).strip()
            customer_pain_points = (data.get('customer_pain_point') or data.get('customer_pain_points', '')).strip()
            customer_preference = data.get('customer_preference', '').strip()
            
            # 格式化处理指令
            instructions = cls.PROCESSING_INSTRUCTIONS.format(
                core_goal=core_goal,
                target_audience=target_audience,
                budget_per_person=budget_per_person,
                gift_preference=gift_preference if gift_preference else '礼品类型偏好',
                customer_pain_points=customer_pain_points,
                customer_preference=customer_preference
            )
            
            return instructions
            
        except Exception as e:
            logger.error(f'构建处理指令失败: {str(e)}')
            # 返回默认指令模板
            return cls.PROCESSING_INSTRUCTIONS.format(
                core_goal='核心目标',
                target_audience='目标受众',
                budget_per_person='人均预算',
                gift_preference='礼品类型偏好',
                customer_pain_points='客户痛点',
                customer_preference='客户偏好'
            )
    
    @classmethod
    def preview_prompt(
        cls,
        requirement_data: Dict
    ) -> Optional[Dict]:
        """
        预览生成的提示词（用于调试和验证）
        
        Args:
            requirement_data: 需求表单数据
            
        Returns:
            Dict: 包含提示词各部分的字典，失败返回None
        """
        try:
            if not cls._validate_requirement_data(requirement_data):
                return None
            
            user_requirements = cls._build_user_requirements(requirement_data)
            processing_instructions = cls._build_processing_instructions(requirement_data)
            full_prompt = cls.generate_prompt(requirement_data)
            
            return {
                'user_requirements': user_requirements,
                'processing_instructions': processing_instructions,
                'full_prompt': full_prompt,
                'character_count': len(full_prompt) if full_prompt else 0
            }
            
        except Exception as e:
            logger.error(f'预览提示词失败: {str(e)}')
            return None